import React from "react";
import ReactReduxContext from "./ReactReduxContext";
import { bindActionCreators } from "../my-redux";

/**
 * PureComponent 当属性和状态没有变化的时候不重新渲染
 * 刚才做的优化是有些值只计算一次，不需要反复计算
 * 因为函数组件没有构造函数，没有地方说只能执行一次，只能用useMemo
 *
 * @param {*} mapStateToProps 把 store 中的 state 映射到组件的 props 上
 * @param {*} mapDispatchToProps 把 store 中的 action 映射到组件的 props 上
 */
function connect(mapStateToProps, mapDispatchToProps) {
  return function (OldComponent) {
    return class extends React.Component {
      static contextType = ReactReduxContext;

      constructor(props, context) {
        super(props);
        const { store } = context;
        const { getState, subscribe, dispatch } = store;
        this.state = mapStateToProps(getState());

        this.unsubscribe = subscribe(() => {
          this.setState(mapStateToProps(getState()));
        });

        let dispatchProps;

        if (typeof mapDispatchToProps === "function") {
          dispatchProps = mapDispatchToProps(dispatch);
        } else if (typeof mapDispatchToProps === "object") {
          dispatchProps = bindActionCreators(mapDispatchToProps, dispatch);
        } else {
          dispatchProps = { dispatch };
        }

        this.dispatchProps = dispatchProps;
      }

      componentWillUnmount() {
        this.unsubscribe();
      }

      render() {
        return (
          <OldComponent
            {...this.props}
            {...this.dispatchProps}
            {...this.state}
          />
        );
      }
    };
  };
}

export default connect;
